//package com.zdp.config;
//
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.zdp.commons.JsonUtils;
//import com.zdp.security.filter.RestAuthenticationFilter;
//import lombok.RequiredArgsConstructor;
//import lombok.extern.slf4j.Slf4j;
//import lombok.val;
//import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
//import org.springframework.context.annotation.Bean;
//import org.springframework.http.HttpStatus;
//import org.springframework.http.MediaType;
//import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
//import org.springframework.security.config.annotation.web.builders.HttpSecurity;
//import org.springframework.security.config.annotation.web.builders.WebSecurity;
//import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
//import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
//import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
//import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
//import org.springframework.security.crypto.password.MessageDigestPasswordEncoder;
//import org.springframework.security.crypto.password.PasswordEncoder;
//import org.springframework.security.web.authentication.AuthenticationFailureHandler;
//import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
//import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
//
//import java.util.HashMap;
//import java.util.Map;
//
///**
// * @author sesshomaru
// * @date 2021/7/2
// */
//@RequiredArgsConstructor
//@Slf4j
//@EnableWebSecurity(debug = true)
//public class 接口和表单共存 extends WebSecurityConfigurerAdapter {
//
//    private final ObjectMapper objectMapper;
//
//    // 用于配置那些路劲需要被拦截处理
//    @Override
//    protected void configure(HttpSecurity http) throws Exception {
//        http
//                // 以下为接口部分
//                .authorizeRequests(req -> req
//                        .antMatchers("/authorize/**").permitAll()
//                        .antMatchers("/admin/**").hasRole("ADMIN")
//                        .antMatchers("/api/**").hasRole("USER")
//                        .anyRequest().authenticated())
//                // 只有表单的方式访问需要配置CSRF而接口方式无需CSRF
//                // 因为无状态操作天然的就可以避免CSRF攻击，因为无状态登录是需要携带Token才可以正常访问的
//                .csrf(csrf -> csrf.ignoringAntMatchers("/api/**", "/admin/**", "/authorize/**"))
//                // 添加自定以拦截器
//                .addFilterAt(restAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
//                // 以下为表单部分
//                .formLogin(form -> form.loginPage("/login")
//                        .usernameParameter("username")
//                        .passwordParameter("password")
//                        .defaultSuccessUrl("/")
//                        .successHandler(jsonAuthenticationSuccessHandler())
//                        .failureHandler(jsonAuthenticationFailureHandler())
//                        .permitAll())
//                .logout(logout -> logout.logoutUrl("/perform_logout"))
//                .rememberMe(rememberMe -> rememberMe.tokenValiditySeconds(30 * 24 * 3600).rememberMeCookieName("someKeyToRemember"));
//    }
//
//    // 实例化自定义的Filter
//    private RestAuthenticationFilter restAuthenticationFilter() throws Exception {
//        RestAuthenticationFilter filter = new RestAuthenticationFilter(objectMapper);
//        filter.setAuthenticationSuccessHandler(jsonAuthenticationSuccessHandler());
//        filter.setAuthenticationFailureHandler(jsonAuthenticationFailureHandler());
//        filter.setAuthenticationManager(authenticationManager());
//        // filter应用在哪个路口上
//        filter.setFilterProcessesUrl("/authorize/login");
//        return filter;
//    }
//
//
//    private AuthenticationFailureHandler jsonAuthenticationFailureHandler() {
//        return (req, res, exp) -> {
//            res.setStatus(HttpStatus.UNAUTHORIZED.value());
//            res.setContentType(MediaType.APPLICATION_JSON_VALUE);
//            res.setCharacterEncoding("UTF-8");
//            Map<String, String> errData = new HashMap<>();
//            errData.put("title", "认证失败");
//            errData.put("details", exp.getMessage());
//            res.getWriter().println(JsonUtils.objectToJson(errData));
//        };
//    }
//
//    private AuthenticationSuccessHandler jsonAuthenticationSuccessHandler() {
//        return (req, res, auth) -> {
//            res.setStatus(HttpStatus.OK.value());
//            // 将auth对象转换为json返回回去
//            res.getWriter().println(JsonUtils.objectToJson(auth));
//            log.debug("认证成功");
//        };
//    }
//
//    // 允许或者拒绝一些请求不同通过认证和授权即可访问资源
//    @Override
//    public void configure(WebSecurity web) throws Exception {
//        // 访问/public/**不做过滤，甚至根本就不会启动任何过滤器进行认证后授权(用于忽略对静态资源文件访问地址的拦截)
//        web.ignoring().mvcMatchers("/public/**", "/error")
//                // PathRequest.toStaticResources().atCommonLocations()配置忽略常用的资源路径如css、js等
//                .requestMatchers(PathRequest.toStaticResources().atCommonLocations());
//    }
//
//    /**
//     * 替代在yml配置的登录时输入的用户名和密码
//     *
//     * @param auth
//     * @throws Exception
//     */
//    @Override
//    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.inMemoryAuthentication()
//                .passwordEncoder(passwordEncoder())
//                .withUser("user")
//                // passwordEncoder().encode("12345678")编码的结果为{bcrypt}$2a$10$Yi00ttApu9syyJdga63ZlO/OmjOObqwZLBroMfLNe3ApqrH1Qdpfe
//                .password(passwordEncoder().encode("12345678"))
//                //.password("{bcrypt}$2a$10$jhS817qUHgOR4uQSoEBRxO58.rZ1dBCmCTjG8PeuQAX4eISf.zowm")
//                .roles("USER", "ADMIN")
//                .and()
//                .withUser("old_user")
//                //new MessageDigestPasswordEncoder("SHA-1").encode("abcd1234") 编码后的值 {eonSRXJVEg4bznmRpzdB4g6HP3YLkhbnrGr1awRR11Y=}1369081093bf215210dbbec5c989c48cdfe102ea"
//                //.password(new MessageDigestPasswordEncoder("SHA-1").encode("abcd1234"))
//                .password("{SHA-1}{eonSRXJVEg4bznmRpzdB4g6HP3YLkhbnrGr1awRR11Y=}1369081093bf215210dbbec5c989c48cdfe102ea")
//                .roles("USER");
//    }
//
//   /* @Bean
//    PasswordEncoder passwordEncoder() {
//        return new BCryptPasswordEncoder();
//    }*/
//
//    @Bean
//    public PasswordEncoder passwordEncoder() {
//        // 默认编码算法的 Id
//        val idForEncode = "bcrypt";
//        // 要支持的多种编码器
//        Map encoders = new HashMap<>();
//        encoders.put(idForEncode, new BCryptPasswordEncoder());
//        encoders.put("SHA-1", new MessageDigestPasswordEncoder("SHA-1"));
//
//        return new DelegatingPasswordEncoder(idForEncode, encoders);
//    }
//}
